package com.dl.filter;

import com.alibaba.fastjson.JSONObject;
import com.dl.config.jwt.BaseResponse;
import com.dl.config.jwt.JwtTokenManager;
import com.dl.properties.JWTProperties;
import com.dl.utils.ConstantField;
import lombok.extern.log4j.Log4j2;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.util.ObjectUtils;
import org.yaml.snakeyaml.representer.BaseRepresenter;

import javax.annotation.Resource;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

/**
 * 自定义登录验证过滤器
 * @author DL
 * @create 2021-06-15 10:51
 */
@Log4j2
public class JwtAuthcFilter extends FormAuthenticationFilter {

    private final JWTProperties jwtProperties;

    private final JwtTokenManager jwtTokenManager;

    public JwtAuthcFilter(JWTProperties jwtProperties, JwtTokenManager jwtTokenManager) {
        this.jwtProperties = jwtProperties;
        this.jwtTokenManager = jwtTokenManager;
    }

    //表示是否允许访问；mappedValue就是[urls]配置中拦截器参数部分，如果允许访问返回true，否则false；
    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        //判断当前请求头中是否带有jwtToken的字符串
        String jwtToken = WebUtils.toHttp(request).getHeader(jwtProperties.getJwtTokenName());
        //如果有，走jwt校验
        log.debug("jwtToken:{}",jwtToken);
        if (jwtToken != null && !jwtToken.equals("")) {

            boolean verifyToken = jwtTokenManager.verifyToken(jwtToken);
            if (verifyToken) {
                return super.isAccessAllowed(request, response, mappedValue);
            }else {
                //如果校验失败
                return false;
            }
        }
        return super.isAccessAllowed(request, response, mappedValue);
    }

    //表示访问拒绝时是否自己处理，如果返回true表示自己不处理且继续拦截器链执行，返回false表示自己已经处理了（比如重定向到另一个页面）。
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        //判断当前请求头中是否带有jwtToken的字符串
        String jwtToken = WebUtils.toHttp(request).getHeader(jwtProperties.getJwtTokenName());
        //如果有，返回json格式应答
        if (jwtToken != null && !jwtToken.equals("")) {
            BaseResponse baseResponse = new BaseResponse(ConstantField.NO_LOGIN_CODE, ConstantField.NO_LOGIN_MESSAGE);
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/json;utf-8");
            response.getWriter().write(JSONObject.toJSONString(baseResponse));
        }
        //如果没有，原始方式应答
        return super.onAccessDenied(request, response);
    }

}
